import echarts from "@/components/echarts/index";
import { deepClone } from "@/utils";
import { chartCfg, setDefault } from "./chartConfig.js";
export const chartStyle = {
  width: "100%",
  height: "400px",
};
export function setDefaultChartCfg() {
  setDefault();
}
// 判断是否包含某些字段 解决：包含这些值的时候图表有高亮
function disposeIncludes(type, name) {
  if (type === "chart::Bar::SW") {
  } else if (type === "chart::Line::SW") {
    return ["平均值"].some((item) => name.includes(item));
  } else if (type === "chart::BarLine::SW") {
    return ["同比", "YOY", "yoy"].some((item) => name.includes(item));
  }
}
let copyChartCfg = []; //存储默认颜色的值(由于series 某个系列会有高亮的，为了保证默认的系列是按照配置的顺序获取颜色值)
//获取配置的颜色 (取一个，删除一个，每次取的都是第一个)
function getChartColor(type) {
  return copyChartCfg[type]["color"].length === 0 ? "" : copyChartCfg[type]["color"].shift();
}
// 设置坐标小数点
let copyData = {};
function setToFixed(value, type) {
  let num = 2;
  if (type == "line") {
    !copyData.isConfig || copyData.lineToFixed === undefined
      ? (copyData["lineToFixed"] = chartCfg.line.toFixedNum)
      : "";
    num = copyData.lineToFixed;
  }
  if (type == "bar") {
    !copyData.isConfig || copyData.barToFixed === undefined ? (copyData["barToFixed"] = chartCfg.bar.toFixedNum) : "";
    num = copyData.barToFixed;
  }
  return value.toFixed(num);
}
// 设置x轴坐标旋转角度
function setRotate(type) {
  let rotate = 60;
  if (type == "line") {
    !copyData.isConfig || copyData.lineRotate === undefined
      ? (copyData["lineRotate"] = copyData.x_list.length < 5 ? 0 : chartCfg.line.lineRotate)
      : "";
    rotate = copyData.lineRotate;
  }
  if (type == "bar") {
    !copyData.isConfig || copyData.barRotate === undefined
      ? (copyData["barRotate"] = copyData.x_list.length < 5 ? 0 : chartCfg.bar.barRotate)
      : "";
    rotate = copyData.barRotate;
  }
  return rotate;
}
//图表--柱状图
export const chartBarSW = class ChartBarSW {
  constructor({ id, data }) {
    this.data = data;
    copyChartCfg = deepClone(chartCfg);
    this.type = "bar";
    this.barCfg = chartCfg[this.type];
    this.highlight = this.barCfg.highlight;

    this.myChart?.clear();
    let chartDom = id instanceof HTMLElement ? id : document.getElementById(id);
    chartDom.style.width = chartStyle.width;
    chartDom.style.height = chartStyle.height;
    this.myChart = echarts.init(chartDom);
    this.initData();
    this.initOption();
    if (!data.isConfig || !data.barMaxMin) {
      let rangeY = this.myChart?.getModel().getComponent("yAxis").axis.scale._extent;
      data.barMaxMin = rangeY;
    }
  }
  initData() {
    let { title, x_list, series, highlight, isConfig } = this.data;
    this.title = title;
    this.x_list = x_list;
    this.legend = null;
    !isConfig
      ? series.forEach((item, index, arr) => {
          let data = item.data;
          let color = item.type === "平均值" ? this.highlight : getChartColor(this.type);
          data.forEach((yData, index, arr) => {
            if (highlight && highlight.includes(x_list[index])) {
              //因为从LLM组直接渲染到界面的时候我已经解析了，现在是块编辑引擎在渲染的时候就不需要在解析了(todo:后来：但是由于高亮色配置化（配置管理-图表配置）之后，之前保存过的不能实时更新过来高亮的颜色)
              // if (yData.itemStyle) return;
              // arr[index] = {
              //   value: yData,
              //   itemStyle: { color: this.highlight },
              // };
              //最新逻辑（配置高亮色之后，也能实时同步过来高亮色）
              if (yData.itemStyle) {
                //之前已经设置过高亮色的 直接赋值就可以了（如果高亮不同的话，就直接替换了）
                yData.itemStyle.color = this.highlight;
              } else {
                //没有设置高亮色的情况
                arr[index] = {
                  value: yData,
                  itemStyle: { color: this.highlight },
                };
              }
            }
          });
          let barCfg = deepClone(this.barCfg);
          item["type"] = "bar";
          item["itemStyle"] = barCfg.itemStyle;
          item["itemStyle"]["color"] = color;
          arr[index] = { ...item, ...barCfg.propertyConfig };
        })
      : "";
    this.grid = { top: 20, left: 0, right: 0, bottom: 10, containLabel: true };
    //有两条线的 展示图例
    if (series.length > 1) {
      this.legend = { top: 40 };
      this.grid.top = 60;
    }
    this.series = series;
  }
  initOption() {
    this.option = {
      animation: false,
      // title: {
      //   left: "center",
      //   text: this.title,
      // },
      legend: this.legend,
      grid: this.grid,
      tooltip: { show: true },
      xAxis: {
        type: "category",
        data: this.x_list,
        axisLabel: {
          // formatter: function (value) {
          //   return value.split("").join("\n");
          // },
          rotate: setRotate("bar"),
          // origin: ["100%", "100%"],
        },
        axisTick: {
          show: false, //刻度线
        },
      },
      yAxis: {
        type: "value",
        axisLine: { show: true },
        // interval: 2, //强制设置坐标轴分割间隔。
        splitLine: {
          show: false,
        },
        axisLabel: {
          formatter: function (value) {
            return setToFixed(value, "bar");
          },
        },
        axisTick: {
          show: true,
          inside: true,
        },
        // 最大值
        max: this.data.barMaxMin ? this.data.barMaxMin[1] : null,
        // 最小值
        min: this.data.barMaxMin ? this.data.barMaxMin[0] : null,
      },
      series: this.series,
    };
    this.myChart.setOption(this.option);
    saveImage(this.myChart, this.data);
  }
};
//图表--线性图
export const chartLineSW = class ChartLineSW {
  constructor({ id, data }) {
    this.data = data;
    copyChartCfg = deepClone(chartCfg);

    this.type = "line";
    this.lineCfg = chartCfg[this.type];
    this.highlight = this.lineCfg.highlight;

    this.myChart?.clear();
    // let chartDom = document.getElementById(id);
    let chartDom = id instanceof HTMLElement ? id : document.getElementById(id);
    chartDom.style.width = chartStyle.width;
    chartDom.style.height = chartStyle.height;
    this.myChart = echarts.init(chartDom);
    this.initData();
    this.initOption();
    if (!data.isConfig || !data.lineMaxMin) {
      let rangeY = this.myChart?.getModel().getComponent("yAxis").axis.scale._extent;
      data.lineMaxMin = rangeY;
    }
  }
  initData() {
    let { title, x_list, series, isConfig } = this.data;
    this.title = title;
    this.x_list = x_list;
    this.legend = null;
    // isConfig 第一次初始化走默认数据 其他根据配置显示
    !isConfig
      ? series.forEach((item, index, arr) => {
          let color = item.name === "平均值" ? this.highlight : getChartColor(this.type);
          let lineCfg = deepClone(this.lineCfg);
          item["type"] = "line";
          item["itemStyle"] = lineCfg.itemStyle;
          item["itemStyle"]["color"] = color;
          item["lineStyle"] = lineCfg.lineStyle;
          arr[index] = { ...item, ...lineCfg.propertyConfig };
        })
      : "";
    this.grid = { top: 20, left: 0, right: 0, bottom: 10, containLabel: true };
    //有两条线的 展示图例
    if (series.length > 1) {
      this.legend = { top: 40 };
      this.grid.top = 60;
    }
    this.series = series;
  }
  initOption() {
    this.option = {
      animation: false,
      // title: { text: this.title },
      legend: this.legend,
      tooltip: {
        trigger: "axis",
      },
      grid: this.grid,
      xAxis: {
        type: "category",
        margin: 20,
        boundaryGap: true, //设置坐标轴两边留白
        data: this.x_list,
        axisLabel: {
          rotate: setRotate("line"), // 旋转角度
        },
      },
      yAxis: {
        type: "value",
        axisLine: { show: true },
        splitLine: {
          show: false,
        },
        axisLabel: {
          formatter: function (value) {
            return setToFixed(value, "line");
          },
        },
        axisTick: {
          show: true,
          inside: true,
        },
        // 最大值
        max: this.data.lineMaxMin ? this.data.lineMaxMin[1] : null,
        // 最小值
        min: this.data.lineMaxMin ? this.data.lineMaxMin[0] : null,
      },
      series: this.series,
    };
    this.myChart.setOption(this.option);
    saveImage(this.myChart, this.data);
  }
};
//图表--柱状线性图
export const chartBarLineSW = class chartBarLineSW {
  constructor({ id, data }) {
    this.data = data;
    copyChartCfg = deepClone(chartCfg);

    this.type = "line";
    this.lineCfg = chartCfg["line"];
    this.barCfg = chartCfg["bar"];
    this.lineHighlight = this.lineCfg.highlight;
    this.barHighlight = this.barCfg.highlight;

    this.myChart?.clear();
    let chartDom = id instanceof HTMLElement ? id : document.getElementById(id);
    chartDom.style.width = chartStyle.width;
    chartDom.style.height = chartStyle.height;
    this.myChart = echarts.init(chartDom);
    this.initData();
    this.initOption();
    if (!data.isConfig || !data.barMaxMin || !data.lineMaxMin) {
      let rangeYLeft = this.myChart?.getModel().getComponent("yAxis", 0).axis.scale._extent;
      let rangeYRight = this.myChart?.getModel().getComponent("yAxis", 1).axis.scale._extent;
      data.barMaxMin = rangeYLeft;
      data.lineMaxMin = rangeYRight;
      // data.barMaxMin = rangeY;
      console.log("最大值", rangeYLeft, rangeYRight);
    }
  }
  initData() {
    let { title, x_list, series, highlight, isConfig } = this.data;
    this.title = title;
    this.x_list = x_list;
    this.legend = null;
    this.yAxis = [
      {
        type: "value",
        axisLine: { show: true },
        // interval: 2, //强制设置坐标轴分割间隔。
        splitLine: {
          show: false,
        },
        axisLabel: {
          formatter: function (value) {
            return setToFixed(value, "bar");
          },
        },
        axisTick: {
          show: true,
          inside: true,
        },
        // 最大值
        max: this.data.barMaxMin ? this.data.barMaxMin[1] : null,
        // 最小值
        min: this.data.barMaxMin ? this.data.barMaxMin[0] : null,
      },
      {
        type: "value",
        name: "yoy", //动态填充
        position: "right",
        axisLine: {
          show: true, //坐标轴线
        },
        axisTick: {
          //坐标轴刻度线
          show: true,
          inside: true,
        },
        //分割线
        splitLine: {
          show: false,
        },
        axisLabel: {
          formatter: function (value) {
            return setToFixed(value, "line");
          },
        },
        // 最大值
        max: this.data.lineMaxMin ? this.data.lineMaxMin[1] : null,
        // 最小值
        min: this.data.lineMaxMin ? this.data.lineMaxMin[0] : null,
      },
    ];

    !isConfig
      ? series.forEach((item, index, arr) => {
          if (disposeIncludes("chart::BarLine::SW", item.name)) {
            item["type"] = "line";
            let lineCfg = deepClone(this.lineCfg);
            item["itemStyle"] = lineCfg.itemStyle;
            item["itemStyle"]["color"] = this.lineHighlight;
            this.yAxis[1].name = item.name;
            item["yAxisIndex"] = 1; //多个y轴的时候，这个一定要设置，不然显示不出来右侧的y轴坐标轴
            item["lineStyle"] = lineCfg.lineStyle;
            arr[index] = { ...item, ...lineCfg.propertyConfig };
          } else {
            item["type"] = "bar";
            this.yAxis[0].name = item.name;
            let barCfg = deepClone(this.barCfg);

            item["itemStyle"] = barCfg.itemStyle;
            item["itemStyle"]["color"] = getChartColor("bar");
            arr[index] = { ...item, ...barCfg.propertyConfig };
          }
        })
      : "";
    this.grid = { top: 20, left: 0, right: 30, bottom: 10, containLabel: true };
    //有两条线的 展示图例
    if (series.length > 1) {
      this.legend = { top: 40 };
      this.grid.top = 60;
    }
    this.series = series;
  }
  initOption() {
    this.option = {
      animation: false,
      // title: {
      //   left: "center",
      //   text: this.title,
      // },
      legend: this.legend,
      grid: this.grid,
      tooltip: { show: true },
      xAxis: {
        type: "category",
        data: this.x_list,
        axisTick: {
          show: false, //刻度线
        },
      },
      yAxis: this.yAxis,
      series: this.series,
    };
    this.myChart.setOption(this.option);
    saveImage(this.myChart, this.data);
  }
};
//把图表设置成base64 格式的图片
function saveImage(myChart, data) {
  let opts = {
    type: "png", // 导出的格式，可选 png, jpeg
    pixelRatio: 1, // 导出的图片分辨率比例，默认为 1。
    backgroundColor: "#fff", // 导出的图片背景色，默认使用 option 里的 backgroundColor
    // 忽略组件的列表，例如要忽略 toolbox 就是 ['toolbox'],一般也忽略了'toolbox'这栏就够了
    // excludeComponents: Array.<string>
  };
  console.log("ECharts动画完成！");
  let resBase64 = myChart.getDataURL(opts); //拿到base64 地址，就好下载了。
  // console.log("this.resBase64", resBase64);
  data.base64 = resBase64;
  data.isConfig = true;
  return;
  //动画加载完之后获取base64数据
  // 监听动画完成事件
  //我把动画关掉了。由于有动画他是异步的，会出现reportData进行转化blocks数据了，但是动画生成的base64还没添加到reportData里面呢
  myChart.on("finished", function () {
    console.log("ECharts动画完成！");
    let resBase64 = myChart.getDataURL(opts); //拿到base64 地址，就好下载了。
    // console.log("this.resBase64", resBase64);
    data.base64 = resBase64;
    data.isConfig = true;
    // 在这里执行动画完成后的代码
  });
}
export const chartRender = ({ id, data }) => {
  let { type } = data;
  //类似于vue的$nextTick 等dom元素渲染元之后
  setTimeout(() => {
    if (!data.data.isConfig) {
      setDefaultChartCfg();
    }
    copyData = data.data;
    if (type === "chart::Bar::SW") {
      new chartBarSW({ id, data: data.data });
    } else if (type === "chart::Line::SW") {
      new chartLineSW({ id, data: data.data });
    } else if (type === "chart::BarLine::SW") {
      new chartBarLineSW({ id, data: data.data });
    }
  });
};
